package com.yuncheng.spcyApi.controller;

import org.apache.commons.collections.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuncheng.spcyApi.alog.annotation.Log;
import com.yuncheng.spcyApi.constant.schedule.ScheduleConstant;
import com.yuncheng.spcyApi.entity.SpcyScheduleMb;
import com.yuncheng.spcyApi.entity.SpcyScheduleSetting;
import com.yuncheng.spcyApi.scheduleJob.ScheduleJobService;
import com.yuncheng.spcyApi.service.ISpcyScheduleMbService;
import com.yuncheng.spcyApi.service.ISpcyScheduleSettingService;
import com.yuncheng.spcyApi.utils.CronUtils;
import com.yuncheng.spcyApi.utils.GetUuIdUtils;
import com.yuncheng.vo.HttpResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

@Api(tags = "审评查验-定时任务配置接口")
@RestController
@RequestMapping("/api/spzx-spcy/scheduleSetting")
public class ScheduleJobController {
    private static final Logger log = LoggerFactory.getLogger(ScheduleJobController.class);

//    @Autowired
//    private CronTaskRegistrar cronTaskRegistrar;

    @Resource
    private ISpcyScheduleSettingService spcyScheduleSettingService;

    @Resource
    private ISpcyScheduleMbService spcyScheduleMbService;

    @Resource
    private ScheduleJobService scheduleJobService;

    @Log(title = "查询定时任务列表")
    @ApiOperation(value = "查询定时任务列表")
    @GetMapping(value = "querySchedulePage")
    public HttpResult<?> querySchedulePage(SpcyScheduleSetting sysJob,
                                             @RequestParam(name = "pageNo",defaultValue = "1")Integer pageNo,
                                             @RequestParam(name = "pageSize",defaultValue = "10")Integer pageSize){
        Page<SpcyScheduleSetting> page = new Page<>(pageNo,pageSize);
        LambdaQueryWrapper<SpcyScheduleSetting> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(sysJob.getRwName()),SpcyScheduleSetting::getRwName,sysJob.getRwName());
        queryWrapper.like(StringUtils.isNotBlank(sysJob.getMethodName()),SpcyScheduleSetting::getMethodName,sysJob.getMethodName());
        queryWrapper.like(StringUtils.isNotBlank(sysJob.getBeanName()),SpcyScheduleSetting::getBeanName,sysJob.getBeanName());
        if (sysJob.getJobStatus() != null){
            queryWrapper.eq(SpcyScheduleSetting::getJobStatus,sysJob.getJobStatus());
        }
//        queryWrapper.eq(StringUtils.isNotBlank(String.valueOf(sysJob.getJobStatus())),SpcyScheduleSetting::getJobStatus,sysJob.getJobStatus());

        queryWrapper.orderByDesc(SpcyScheduleSetting::getCreateTime);
        IPage<SpcyScheduleSetting> schedulePage = spcyScheduleSettingService.page(page, queryWrapper);
        return HttpResult.ok(schedulePage);
    }

    /**
     * 添加定时任务
     *
     * @param sysJob
     * @return
     */
    @Log(title = "添加定时任务")
    @ApiOperation(value = "添加定时任务")
    @PostMapping("add")
    public HttpResult<?> add(@RequestBody SpcyScheduleSetting sysJob) {
        if (StringUtils.isBlank(sysJob.getRwName())){
            return HttpResult.error("添加失败，任务名称不能为空");
        }
        if (StringUtils.isBlank(sysJob.getBeanName())){
            return HttpResult.error("添加失败，bean名称不能为空");
        }
        if (StringUtils.isBlank(sysJob.getMethodName())){
            return HttpResult.error("添加失败，方法名称不能为空");
        }
        // 判断是否存在该 bean对象
        if (!ScheduleConstant.getScheduleBeanList().contains(sysJob.getBeanName())){
            return HttpResult.error("系统中不存在，该bean对象【"+sysJob.getBeanName()+"】");
        }

        // 判断bean里面是否存在该方法
        boolean isExistMehtod = ScheduleConstant.getBeanInMethod(sysJob.getBeanName(), sysJob.getMethodName());
        if (!isExistMehtod){
            return HttpResult.error("【"+sysJob.getBeanName()+"】该bean对象中，不存在该方法【"+sysJob.getMethodName()+"】");
        }

        if (sysJob.getMgdsfzzx() == null){
            sysJob.setMgdsfzzx(1);
        }

        // 计算cron表达式 0 0/30 * * * ?
        sysJob.setCronExpression(CronUtils.getCronWithStr(String.valueOf(sysJob.getMgdsfzzx())));

        if (sysJob.getJobStatus() == null){
            sysJob.setJobStatus(0);
        }

        sysJob.setId(GetUuIdUtils.ReplaceUuId());
        boolean insert = spcyScheduleSettingService.save(sysJob);
        if (!insert) {
            return HttpResult.error("添加失败，请刷新重试");
        }else {
            if (StringUtils.isNotBlank(String.valueOf(sysJob.getJobStatus())) && sysJob.getJobStatus().equals(1)) {
                // 添加成功,并且状态是1，直接放入任务器
                /*SchedulingRunnable task = new SchedulingRunnable(sysJob.getBeanName(), sysJob.getMethodName(), sysJob.getMethodParams());
                cronTaskRegistrar.addCronTask(task, sysJob.getCronExpression());*/
                scheduleJobService.addJob(sysJob);
            }
        }
        return HttpResult.ok("添加成功");
    }

    /**
     * 修改定时任务
     *
     * @param sysJob
     * @return
     */
    @Log(title = "修改定时任务")
    @ApiOperation(value = "修改定时任务")
    @PostMapping("update")
    public HttpResult<?> update(@RequestBody SpcyScheduleSetting sysJob) {
        if (StringUtils.isBlank(sysJob.getId())){
            return HttpResult.error("参数不能为空");
        }
        if (StringUtils.isBlank(sysJob.getRwName())){
            return HttpResult.error("添加失败，任务名称不能为空");
        }
        if (StringUtils.isBlank(sysJob.getBeanName())){
            return HttpResult.error("添加失败，bean名称不能为空");
        }
        if (StringUtils.isBlank(sysJob.getMethodName())){
            return HttpResult.error("添加失败，方法名称不能为空");
        }
        // 判断是否存在该 bean对象
        if (!ScheduleConstant.getScheduleBeanList().contains(sysJob.getBeanName())){
            return HttpResult.error("系统中不存在，该bean对象【"+sysJob.getBeanName()+"】");
        }

        // 判断bean里面是否存在该方法
        boolean isExistMehtod = ScheduleConstant.getBeanInMethod(sysJob.getBeanName(), sysJob.getMethodName());
        if (!isExistMehtod){
            return HttpResult.error("【"+sysJob.getBeanName()+"】该bean对象中，不存在该方法【"+sysJob.getMethodName()+"】");
        }

        if (sysJob.getMgdsfzzx() == null){
            sysJob.setMgdsfzzx(1);
        }

        // 计算cron表达式 0 0/30 * * * ?
        sysJob.setCronExpression(CronUtils.getCronWithStr(String.valueOf(sysJob.getMgdsfzzx())));

        if (sysJob.getJobStatus() == null){
            sysJob.setJobStatus(0);
        }

        // 查询修改前任务
        SpcyScheduleSetting existedSysJob = spcyScheduleSettingService.getById(sysJob.getId());
        if (existedSysJob == null){
            return HttpResult.error("定时任务不存在");
        }

        boolean update = spcyScheduleSettingService.updateById(sysJob);
        if (!update) {
            return HttpResult.error("保存失败，请刷新重试");
        } else {
            // 如果状态是0则清除任务
            if (sysJob.getJobStatus().equals(0)) {
                // 否则清除任务
                /* SchedulingRunnable task = new SchedulingRunnable(existedSysJob.getBeanName(), existedSysJob.getMethodName(), existedSysJob.getMethodParams());
                cronTaskRegistrar.removeCronTask(task);*/
                scheduleJobService.pauseJob(existedSysJob);
            }else {
                // 修改成功,则先删除任务器中的任务,并重新添加
                /*SchedulingRunnable task1 = new SchedulingRunnable(existedSysJob.getBeanName(), existedSysJob.getMethodName(), existedSysJob.getMethodParams());
                cronTaskRegistrar.removeCronTask(task1);*/

                SpcyScheduleSetting existedSysJob2 = spcyScheduleSettingService.getById(sysJob.getId());
                // 如果修改后的任务状态是1就加入任务器
               /* SchedulingRunnable task = new SchedulingRunnable(existedSysJob2.getBeanName(), existedSysJob2.getMethodName(), existedSysJob2.getMethodParams());
                cronTaskRegistrar.addCronTask(task, existedSysJob2.getCronExpression());*/
                scheduleJobService.pauseJob(existedSysJob2);
            }
        }
        return HttpResult.ok("保存成功");
    }

    /**
     * 删除任务
     *
     * @param ids
     * @return
     */
    @Log(title = "删除定时任务")
    @ApiOperation(value = "删除定时任务")
    @ApiImplicitParam(name = "id",value = "id逗号分割")
    @DeleteMapping("delele")
    public HttpResult<?> del(@RequestParam("id") String ids) {
        // 先查询要删除的任务信息
        // 查询修改前任务
        if (StringUtils.isBlank(ids)){
            return HttpResult.error("参数不能为空");
        }
        List<String> idsList = Arrays.asList(ids.split(","));
        if (CollectionUtils.isNotEmpty(idsList)) {
            for (String id : idsList) {
                SpcyScheduleSetting existedSysJob = spcyScheduleSettingService.getById(id);
                // 删除
                boolean del = spcyScheduleSettingService.removeById(id);
                if (!del) {
                    return HttpResult.error("删除失败");
                } else {
                    // 删除成功时要清除定时任务器中的对应任务
                    scheduleJobService.pauseJob(existedSysJob);
                }
            }
        }
        return HttpResult.error("删除成功");
    }

    @Log(title = "通过id查询定时任务")
    @ApiOperation(value = "通过id查询定时任务")
    @GetMapping(value = "queryById")
    public HttpResult<?> queryById(String id){
        SpcyScheduleSetting setting = spcyScheduleSettingService.getById(id);
        return HttpResult.ok(setting);
    }

    @Log(title = "选择启动定时任务")
    @ApiOperation(value = "选择启动定时任务")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "id",value = "任务模板id",required = true),
            @ApiImplicitParam(name = "autoStopFlag",value = "定时任务执行一次自动停止（默认false【不停止】/true【停止】）",required = true)
    })
    @GetMapping(value = "selectScheduleJob")
    public HttpResult<?> selectScheduleJob(@RequestParam("id")String id,
                                           @RequestParam(name = "autoStopFlag",defaultValue = "false")boolean autoStopFlag){
        if (StringUtils.isBlank(id)){
            return HttpResult.error("参数不能为空");
        }
        SpcyScheduleMb mb = spcyScheduleMbService.getById(id);
        if (mb == null){
            return HttpResult.error("当前选择的定时任务模板，不存在");
        }
        SpcyScheduleSetting setting = new SpcyScheduleSetting();
        setting.setId(GetUuIdUtils.ReplaceUuId());
        setting.setJobStatus(1);
        setting.setRwName(mb.getMbName());
        setting.setBeanName(mb.getBeanName());
        setting.setMethodName(mb.getMethodName());
        setting.setMethodParams(mb.getMethodParams());
        setting.setCronExpression(mb.getCronExpression());
        setting.setMgdsfzzx(mb.getMgdsfzzx());
        boolean falg = spcyScheduleSettingService.save(setting);
        if (!falg){
            return HttpResult.error("保存失败");
        }else {
            // true （执行一次、自动停止、定时任务）
            if (autoStopFlag){
                /*SchedulingRunnable task = new SchedulingRunnable(cronTaskRegistrar,spcyScheduleSettingService,setting.getId(),setting.getBeanName(), setting.getMethodName(), setting.getMethodParams());
                cronTaskRegistrar.addCronTask(task, setting.getCronExpression());*/
                scheduleJobService.executeOneJob(setting);
            }else {
                // 添加成功,并且状态是1，直接放入任务器
                /*SchedulingRunnable task = new SchedulingRunnable(setting.getBeanName(), setting.getMethodName(), setting.getMethodParams());
                cronTaskRegistrar.addCronTask(task, setting.getCronExpression());*/
                scheduleJobService.addJob(setting);
            }
        }
        return HttpResult.ok("选择启动成功");
    }

    @Log(title = "启动定时任务")
    @ApiOperation(value = "启动定时任务")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "id",value = "任务模板id",required = true),
            @ApiImplicitParam(name = "autoStopFlag",value = "定时任务执行一次自动停止（默认false【不停止】/true【停止】）",required = true)
    })
    @GetMapping(value = "beginScheduleJob")
    public HttpResult<?> beginScheduleJob(@RequestParam("id")String id,
                                          @RequestParam(name = "autoStopFlag",defaultValue = "false")boolean autoStopFlag){
        SpcyScheduleSetting sysJob = spcyScheduleSettingService.getById(id);
        if (sysJob == null){
            return HttpResult.error("该定时任务不存在，请刷新重试");
        }
        sysJob.setJobStatus(1);
        boolean flag = spcyScheduleSettingService.updateById(sysJob);
        if (!flag){
            return HttpResult.error("启动定时任务失败，请刷新重试");
        }else {
            // true （执行一次、自动停止、定时任务）
            if (autoStopFlag){
                /*SchedulingRunnable task = new SchedulingRunnable(cronTaskRegistrar,spcyScheduleSettingService,sysJob.getId(),sysJob.getBeanName(), sysJob.getMethodName(), sysJob.getMethodParams());
                cronTaskRegistrar.addCronTask(task, sysJob.getCronExpression());*/
                scheduleJobService.executeOneJob(sysJob);
            }else {
                // 添加成功,并且状态是1，直接放入任务器
                /*SchedulingRunnable task = new SchedulingRunnable(sysJob.getBeanName(), sysJob.getMethodName(), sysJob.getMethodParams());
                cronTaskRegistrar.addCronTask(task, sysJob.getCronExpression());*/
                scheduleJobService.addJob(sysJob);
            }
        }
        return HttpResult.ok("启动成功");
    }

    @Log(title = "暂定定时任务")
    @ApiOperation(value = "暂定定时任务")
    @GetMapping(value = "stopScheduleJob")
    public HttpResult<?> stopScheduleJob(@RequestParam("id")String id){
        SpcyScheduleSetting sysJob = spcyScheduleSettingService.getById(id);
        if (sysJob == null){
            return HttpResult.error("该定时任务不存在，请刷新重试");
        }
        sysJob.setJobStatus(0);
        boolean flag = spcyScheduleSettingService.updateById(sysJob);
        if (!flag){
            return HttpResult.error("暂停定时任务失败，请刷新重试");
        }else {
            // 删除成功时要清除定时任务器中的对应任务
            /*SchedulingRunnable task = new SchedulingRunnable(sysJob.getBeanName(), sysJob.getMethodName(), sysJob.getMethodParams());
            cronTaskRegistrar.removeCronTask(task);*/
            scheduleJobService.pauseJob(sysJob);
        }
        return HttpResult.ok("暂停成功");
    }
}
